/**
* Created with CLion.
* User:Lenovo
* Date:2023-05-21
* Time:2:06
* Description:洛谷 P1182  数列分段 Section II
*/

#include <stdio.h>
#include <stdbool.h>

#define MAX(a, b) ((a) > (b) ? (a) : (b))

typedef long long ll;

bool check(ll mid, const int sum[], int m, int n)
{
    int count = 1;// 计数器，判断数列分成了几段
    int now = 0;// 用于记录分段之后下一段的起始位置
    for (int i = 0; i < n; i++)
    {
        int tmp;
        if (count == 1)
        {
            tmp = sum[i];
        }
        else
        {
            tmp = sum[i] - sum[now];
        }
        if (tmp > mid) // 相减之后就是这一段的和，如果大于 mid，题目的条件就不成立了，所以在此处分段
        {
            count++;
            now = --i;
        }
    }
    if (count > m) // 大于 m，说明 mid 小了
    {
        return true;
    }
    else // 等于 m，有可能还能往里塞入数据，因此算作 mid 大了
    {
        return false;
    }
}

int main()
{
    int m, n;
    scanf("%d %d", &n, &m);
    int num[n];
    for (int i = 0; i < n; i++)
    {
        scanf("%d", num + i);
    }

    int sum[n];
    ll left = num[0], right;// 二分法的左端和右端 - 左端是将数列全部分段，每一段的最大值(数组里最大的数)，右端是数列不分段(一段)，数列的和
    sum[0] = num[0];
    for (int i = 1; i < n; i++)
    {
        sum[i] = sum[i - 1] + num[i];// 前缀和
        left = MAX(left, num[i]);
    }
    right = sum[n - 1];

    while (left < right)
    {
        ll mid = (left + right) >> 1;
        if (check(mid, sum, m, n))
        {
            left = mid + 1;
        }
        else
        {
            right = mid;// 与 check 函数相通，如果出现这种情况，说明 mid 可能还是需要的，所以要保留 mid
        }
    }

    printf("%lld", left);// right 也行

    /* 有关上面的二分法的解释：
     * 现在只知道两端的大小，要求求出中间的某个数 - 单凭两个数无法做到，需要题目中给的条件来编写 check 函数
     * 也就是说，二分法中的 check 函数是灵活的，也是整个二分法中最核心的地方，其效果是在只知道头尾两端的数的情况下，引导二分方向(mid 变小还是变大)
     * 在本题中，check 函数的作用是通过参数 mid，判断在中值为 mid 的情况下，整个数列要分成几段才满足题意(n)
     * 如果分的段大于 n，说明要分很多段才能满足最大值为 mid，进而说明 mid 小了，反之说明 mid 大了
     * 在 check 引导完成之后，进入正常的二分环节，范围依次缩小，直到找到所需要的数
     * 好诡异的思路啊(划掉)
     */

    /* 有关 "最大值最小" 和 "最小值最大"：
     * 如果是类似第一种的问题，那么说明满足比答案大的数字也都满足题意，只不过不是最小的
     * 类似第二种的问题，说明满足比答案小的数字也都满足题意，只不过不是最大的
     * 那就好说了，碰到第一种问题就调整 mid，满足条件右端就左移，不满足的话左端就右移，第二种也一样
     * 突然感觉，使用 check 函数就是替换了 mid >= x 这个条件，本质上是通过 check 缩小了范围
     */

    return 0;
}